import { Scheduler } from './Scheduler';
import { ACService } from './ACService';
import { BillingService } from './BillingService';
import type { RoomState, ServiceRequest, Bill, StatisticsReport, CheckInRecord } from '../types';
import { ACMode, FanSpeed, RoomStatus } from '../types';
import { MAX_SERVICE_OBJECTS, WAIT_TIME, COMMAND_DEBOUNCE_TIME } from '../constants';

/**
 * 中央控制器
 * 协调调度服务、空调服务和计费服务
 */
export class CentralController {
  private scheduler: Scheduler;
  private acService: ACService;
  public billingService: BillingService;
  private lastCommandTime: Map<string, number> = new Map();
  private pendingCommands: Map<string, ReturnType<typeof setTimeout>> = new Map();
  private checkIntervals: Map<string, ReturnType<typeof setInterval>> = new Map();
  private stateChangeCallbacks: Set<() => void> = new Set();
  private checkInRecords: Map<string, CheckInRecord> = new Map(); // 入住记录

  constructor(maxServiceObjects: number = MAX_SERVICE_OBJECTS, waitTime: number = WAIT_TIME) {
    this.scheduler = new Scheduler(maxServiceObjects, waitTime);
    this.acService = new ACService();
    this.billingService = new BillingService();
    
    // 注册调度器回调
    this.scheduler.onRoomMovedToWaiting((roomId: string) => {
      // 房间被移到等待队列，停止送风
      this.acService.setWaiting(roomId);
      this.notifyStateChange();
    });
    
    this.scheduler.onRoomMovedToServing((roomId: string) => {
      // 房间从等待队列移到服务队列，开始送风
      this.acService.startServing(roomId);
      this.notifyStateChange();
    });
  }

  /**
   * 办理入住（前台功能）
   * @param roomId 房间号
   * @param mode 空调模式（制冷/制热）
   * @param guestName 客户姓名（可选）
   * @param guestPhone 客户电话（可选）
   * @returns 入住记录和房间状态
   */
  checkIn(roomId: string, mode: ACMode, guestName?: string, guestPhone?: string): {
    success: boolean;
    message: string;
    checkInRecord?: CheckInRecord;
    roomState?: RoomState;
  } {
    // 1. 检查房间是否已被占用
    const existingCheckIn = this.checkInRecords.get(roomId);
    if (existingCheckIn) {
      return {
        success: false,
        message: `房间 ${roomId} 已被占用，请选择其他房间`
      };
    }

    // 2. 初始化房间（如果尚未初始化）
    let roomState = this.acService.getRoomState(roomId);
    if (!roomState) {
      roomState = this.initRoom(roomId, mode);
    } else if (roomState.isOn) {
      return {
        success: false,
        message: `房间 ${roomId} 空调正在运行中，无法办理入住`
      };
    }

    // 3. 创建入住记录
    const checkInRecord: CheckInRecord = {
      roomId,
      guestName,
      guestPhone,
      checkInTime: Date.now(),
      mode
    };

    this.checkInRecords.set(roomId, checkInRecord);

    // 4. 通知状态变化
    this.notifyStateChange();

    return {
      success: true,
      message: `房间 ${roomId} 入住办理成功`,
      checkInRecord,
      roomState
    };
  }

  /**
   * 获取入住记录
   */
  getCheckInRecord(roomId: string): CheckInRecord | null {
    return this.checkInRecords.get(roomId) || null;
  }

  /**
   * 获取所有已入住的房间号
   */
  getOccupiedRooms(): string[] {
    return Array.from(this.checkInRecords.keys());
  }

  /**
   * 初始化房间（内部方法，由checkIn调用）
   */
  initRoom(roomId: string, mode: ACMode): RoomState {
    const roomState = this.acService.initRoom(roomId, mode);
    
    // 注册状态变化回调
    this.acService.onStateChange(roomId, (state) => {
      this.notifyStateChange();
      
      // 检查是否达到目标温度
      if (state.status === RoomStatus.TARGET_REACHED) {
        // 释放服务对象，让调度器可以分配给其他等待的房间
        this.scheduler.releaseService(roomId);
        // 启动重启检查，监控温度偏离
        this.startRestartCheck(roomId);
      }
    });

    return roomState;
  }

  /**
   * 开机
   */
  turnOn(roomId: string): RoomState | null {
    const roomState = this.acService.turnOn(roomId);
    this.notifyStateChange();
    return roomState;
  }

  /**
   * 关机
   */
  turnOff(roomId: string): RoomState | null {
    // 释放服务对象
    this.scheduler.releaseService(roomId);
    
    // 关机
    const roomState = this.acService.turnOff(roomId);
    
    // 停止重启检查
    this.stopRestartCheck(roomId);
    
    this.notifyStateChange();
    return roomState;
  }

  /**
   * 发送温控请求（带防抖）
   */
  sendRequest(roomId: string, targetTemp: number, fanSpeed: FanSpeed): void {
    const now = Date.now();
    const lastTime = this.lastCommandTime.get(roomId) || 0;
    const timeDiff = now - lastTime;

    // 清除之前的待处理命令
    const pendingTimer = this.pendingCommands.get(roomId);
    if (pendingTimer) {
      clearTimeout(pendingTimer);
    }

    // 如果时间间隔小于1秒，延迟发送，只发送最后一次
    if (timeDiff < COMMAND_DEBOUNCE_TIME) {
      const timer = setTimeout(() => {
        this.executeRequest(roomId, targetTemp, fanSpeed);
        this.lastCommandTime.set(roomId, Date.now());
        this.pendingCommands.delete(roomId);
      }, COMMAND_DEBOUNCE_TIME - timeDiff);
      
      this.pendingCommands.set(roomId, timer);
    } else {
      // 立即发送
      this.executeRequest(roomId, targetTemp, fanSpeed);
      this.lastCommandTime.set(roomId, now);
    }
  }

  /**
   * 执行请求
   */
  private executeRequest(roomId: string, targetTemp: number, fanSpeed: FanSpeed): void {
    const roomState = this.acService.getRoomState(roomId);
    if (!roomState || !roomState.isOn) {
      return;
    }

    // 检查是否只是调温
    const isTempChangeOnly = roomState.fanSpeed === fanSpeed && roomState.targetTemp !== targetTemp;

    // 更新目标温度
    this.acService.setTargetTemp(roomId, targetTemp);

    // 如果风速改变，需要重新请求调度
    if (roomState.fanSpeed !== fanSpeed) {
      this.acService.setFanSpeed(roomId, fanSpeed);
      
      // 创建服务请求
      const request: ServiceRequest = {
        roomId,
        targetTemp,
        fanSpeed,
        timestamp: Date.now(),
        currentTemp: roomState.currentTemp
      };

      // 提交到调度器
      const result = this.scheduler.handleRequest(request);

      if (result.granted) {
        // 开始送风
        this.acService.startServing(roomId);
      } else if (result.isWaiting) {
        // 设置为等待状态
        this.acService.setWaiting(roomId);
      }
    } else if (!isTempChangeOnly && roomState.status !== RoomStatus.SERVING) {
      // 如果不是仅调温，且当前没有在服务中，则请求服务
      const request: ServiceRequest = {
        roomId,
        targetTemp,
        fanSpeed,
        timestamp: Date.now(),
        currentTemp: roomState.currentTemp
      };

      const result = this.scheduler.handleRequest(request);

      if (result.granted) {
        this.acService.startServing(roomId);
      } else if (result.isWaiting) {
        this.acService.setWaiting(roomId);
      }
    }

    this.notifyStateChange();
  }

  /**
   * 启动重启检查
   */
  private startRestartCheck(roomId: string): void {
    this.stopRestartCheck(roomId);

    const interval = setInterval(() => {
      const needRestart = this.acService.checkRestart(roomId);
      if (needRestart) {
        const roomState = this.acService.getRoomState(roomId);
        if (roomState) {
          // 重新发送服务请求
          const request: ServiceRequest = {
            roomId,
            targetTemp: roomState.targetTemp,
            fanSpeed: roomState.fanSpeed,
            timestamp: Date.now(),
            currentTemp: roomState.currentTemp
          };

          const result = this.scheduler.handleRequest(request);

          if (result.granted) {
            this.acService.startServing(roomId);
          } else if (result.isWaiting) {
            this.acService.setWaiting(roomId);
          }

          this.notifyStateChange();
        }
      }
    }, 1000);

    this.checkIntervals.set(roomId, interval);
  }

  /**
   * 停止重启检查
   */
  private stopRestartCheck(roomId: string): void {
    const interval = this.checkIntervals.get(roomId);
    if (interval) {
      clearInterval(interval);
      this.checkIntervals.delete(roomId);
    }
  }

  /**
   * 更新服务时长、费用和当前温度
   */
  updateServiceMetrics(): void {
    const serviceQueue = this.scheduler.getServiceQueue();
    const waitingQueue = this.scheduler.getWaitingQueue();
    
    // 更新服务队列
    serviceQueue.forEach(service => {
      const roomState = this.acService.getRoomState(service.roomId);
      if (roomState) {
        const costInfo = this.acService.getCurrentCost(service.roomId);
        this.scheduler.updateServiceDuration(
          service.roomId,
          costInfo.duration,
          costInfo.powerConsumption,
          costInfo.cost,
          roomState.currentTemp
        );
      }
    });

    // 更新等待队列的温度
    waitingQueue.forEach(waiting => {
      const roomState = this.acService.getRoomState(waiting.roomId);
      if (roomState) {
        this.scheduler.updateWaitingTemp(waiting.roomId, roomState.currentTemp);
      }
    });
  }

  /**
   * 设置工作模式
   */
  setMode(roomId: string, mode: ACMode): void {
    this.acService.setMode(roomId, mode);
    this.notifyStateChange();
  }

  /**
   * 退房结账
   */
  checkout(roomId: string): Bill | null {
    const roomState = this.acService.getRoomState(roomId);
    if (!roomState) {
      return null;
    }

    // 获取入住记录
    const checkInRecord = this.checkInRecords.get(roomId);
    if (!checkInRecord) {
      console.warn(`房间 ${roomId} 没有入住记录，无法结账`);
      return null;
    }

    // 如果空调还在运行，先关机
    if (roomState.isOn) {
      this.turnOff(roomId);
    }

    // 生成账单
    const bill = this.billingService.generateBill(
      roomState, 
      checkInRecord.checkInTime, 
      Date.now()
    );

    // 清理房间和入住记录
    this.acService.cleanupRoom(roomId);
    this.checkInRecords.delete(roomId);

    // 通知状态变化
    this.notifyStateChange();

    return bill;
  }

  /**
   * 获取账单
   */
  getBill(roomId: string): Bill | null {
    return this.billingService.getBill(roomId);
  }

  /**
   * 生成统计报表
   */
  generateStatistics(startTime: number, endTime: number): StatisticsReport {
    return this.billingService.generateStatisticsReport(startTime, endTime);
  }

  /**
   * 获取房间状态
   */
  getRoomState(roomId: string): RoomState | null {
    return this.acService.getRoomState(roomId);
  }

  /**
   * 获取所有房间状态
   */
  getAllRoomStates(): RoomState[] {
    return this.acService.getAllRoomStates();
  }

  /**
   * 获取服务队列
   */
  getServiceQueue() {
    return this.scheduler.getServiceQueue();
  }

  /**
   * 获取等待队列
   */
  getWaitingQueue() {
    return this.scheduler.getWaitingQueue();
  }

  /**
   * 注册状态变化回调
   */
  onStateChange(callback: () => void): void {
    this.stateChangeCallbacks.add(callback);
  }

  /**
   * 取消注册状态变化回调
   */
  offStateChange(callback: () => void): void {
    this.stateChangeCallbacks.delete(callback);
  }

  /**
   * 通知状态变化
   */
  private notifyStateChange(): void {
    this.stateChangeCallbacks.forEach(callback => callback());
  }

  /**
   * 一键关机（关闭所有房间的空调）
   */
  turnOffAll(): void {
    const rooms = this.acService.getAllRoomStates();
    rooms.forEach(room => {
      if (room.isOn) {
        this.turnOff(room.roomId);
      }
    });
    this.notifyStateChange();
  }

  /**
   * 一键开机（开启所有房间的空调）
   */
  turnOnAll(): void {
    const rooms = this.acService.getAllRoomStates();
    
    // 一次性完成开机和发送请求
    rooms.forEach(room => {
      if (!room.isOn) {
        // 开机
        this.turnOn(room.roomId);
        
        // 直接执行请求，绕过防抖（批量操作不需要防抖）
        const roomState = this.acService.getRoomState(room.roomId);
        if (roomState && roomState.isOn) {
          this.executeRequest(room.roomId, roomState.targetTemp, roomState.fanSpeed);
          this.lastCommandTime.set(room.roomId, Date.now());
        }
      }
    });
    
    this.notifyStateChange();
  }

  /**
   * 清空等待队列
   */
  clearWaitingQueue(): void {
    // 获取所有等待中的房间ID并清空队列
    const clearedRoomIds = this.scheduler.clearAllWaiting();
    
    // 将这些房间设置为待机状态
    clearedRoomIds.forEach(roomId => {
      const room = this.acService.getRoomState(roomId);
      if (room && room.isOn && room.status === RoomStatus.WAITING) {
        // 停止等待，回到待机状态
        this.acService.setStandby(roomId);
      }
    });
    
    this.notifyStateChange();
  }

  /**
   * 清理所有资源
   */
  destroy(): void {
    this.scheduler.destroy();
    this.acService.destroy();
    
    this.pendingCommands.forEach(timer => clearTimeout(timer));
    this.pendingCommands.clear();
    
    this.checkIntervals.forEach(interval => clearInterval(interval));
    this.checkIntervals.clear();
    
    this.stateChangeCallbacks.clear();
  }
}

